#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include "sequeue.h"

pthread_mutex_t mtx;//初始化
pthread_cond_t cond;
sequeue_t* queue;

void* producer(void* argc)//生产者
{
	int id = *(int*)argc;//转换参数
	while (1)
	{
		sleep(3);
		int data=rand()%100+1;//生成随机数
		pthread_mutex_lock(&mtx);
		if(IsFullSequeue(queue)==1)//判断队列是否为满，满则阻塞并解锁
		{
			pthread_cond_wait(&cond,&mtx);
		}
		InSequeue(queue,data);//数据入队
		printf("the producer pthread id is:%d\n",id);
		printf("\n");
		pthread_cond_signal(&cond);//告知消费者
		pthread_mutex_unlock(&mtx);
	}
	return NULL;
}

void* consumer(void* argc)//消费者
{
	int id = *(int*)argc;//转换参数
	while(1)
	{
		sleep(3);
		pthread_mutex_lock(&mtx);
		if(IsEmptySequeue(queue)==1)//判断队列是否为空，空则阻塞并解锁
		{
			pthread_cond_wait(&cond,&mtx);
		}
		int data=OutSequeue(queue);//数据出队
		printf("the consumer pthread id is:%d\n",id);
		printf("the data of pthread is:%d\n",data);
		printf("\n");
		pthread_cond_signal(&cond);//告知生产者
		pthread_mutex_unlock(&mtx);
	}
	return NULL;
}

int main(void)
{
	sequeue_t* p = NULL;
    pthread_t tid;

	queue=CreateEmptySequeue();//创建队列
	if(NULL==queue)
	{
		perror("queue create err\n");
		return 0;
	}

    if (pthread_cond_init(&cond,NULL)!=0)//创建条件变量
    {
        perror("cond init err\n");
		free(queue);
		queue=NULL;
        return -1;
    }
    if (pthread_mutex_init(&mtx,NULL)==-1)//创建互斥锁
    {
        perror("mtx init err\n");
		free(queue);
		queue=NULL;
		pthread_cond_destroy(&cond);
        return -1;
    }

	int n=0;
	printf("please input the num of producer:\n");//从键盘输入生产者的个数
	scanf("%d",&n);
    
	for (int i = 1; i <= n; i++)//循环创建生产者线程
	{
		if(pthread_create(&tid,NULL,producer,&i)!=0)
    	{
			perror("pthread create err\n");
			free(queue);
			queue=NULL;
			pthread_mutex_destroy(&mtx);
			pthread_cond_destroy(&cond);
        	return -1;
    	}
		usleep(100);
	}

	printf("please input the num of consumer:\n");//从键盘输入消费者的个数
	scanf("%d",&n);
	for (int j = 1; j <= n; j++)//循环创建消费者线程
	{
		if(pthread_create(&tid,NULL,consumer,&j)!=0)
		{
			perror("pthread create err\n");
			free(queue);
			queue=NULL;
			pthread_mutex_destroy(&mtx);
			pthread_cond_destroy(&cond);
			return -1;
		}
		usleep(100);
	}

	pthread_join(tid,NULL);
    pthread_mutex_destroy(&mtx);//销毁
    pthread_cond_destroy(&cond);
	free(queue);
	queue = NULL;

	return 0;
}